#define VB

using System;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;

namespace NCover
{
	using Objects;
	using Utilities;

	public delegate void Message(string msg);

	/// <summary>
	/// Summary description for NCover.
	/// </summary>
	public class NCoverTaskImpl 
	{
		readonly string _directory;
		readonly Message _info, _debug;

		public NCoverTaskImpl(NCover.Actions.NCoverAction ncoverAction)
		{
			_info = ncoverAction.InfoOutput;
			_debug = ncoverAction.DebugOutput;
			_directory = ncoverAction.Counter.PublishDirectory;
			_info(String.Format("Instrumenting {0} files for test coverage analysis.", ncoverAction.Filenames.Count)); 

			ArrayList coveragePoints = new ArrayList();
			NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(232); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(229); NCover.NCoverCheck.Add(229); NCover.NCoverCheck.Add(228); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); foreach (string filename in ncoverAction.Filenames)
			{
				//Ignore recursive problems...
				if (filename.EndsWith("NCoverCheck.cs"))
				{
					continue;
				}

				_debug("instrumenting file: " + filename);
				coveragePoints.AddRange(InstrumentSourceFile(coveragePoints.Count, filename));
			}

			string expectedFilename = Path.Combine(ncoverAction.Counter.PublishDirectory, ncoverAction.Counter.ReportName + Coverage.EXPECTED_EXTENSION);
			_debug(String.Format("Generating expected coverage document to {0}.", expectedFilename));
			
			Coverage coverage = new Coverage();
			coverage.Type = "expectedCoverage";
			coverage.Counter = ncoverAction.Counter;
			coverage.CoveragePoints = (CoveragePoint[]) coveragePoints.ToArray(typeof(CoveragePoint));
			
			Coverage.SaveCoverage(new FileStream(expectedFilename, FileMode.Create), coverage);
			
			if (File.Exists(NCoverCheck.DESTINATION_FILENAME) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(231) && NCover.NCoverCheck.Add(231) && NCover.NCoverCheck.Add(230) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232))
			{
				_debug("Deleting stale actual coverage file @ " + NCoverCheck.DESTINATION_FILENAME);
				File.Delete(NCoverCheck.DESTINATION_FILENAME);
			}

		}

		public CoveragePoint[] InstrumentSourceFile( int baseCoverageIndex, String filename)
		{
			string _uninstrumentedSrc;	
			using(StreamReader reader = new StreamReader(filename))
			{
				_uninstrumentedSrc = reader.ReadToEnd();
			}

			IList remarks;

			if (filename.EndsWith(".vb") && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(231) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233))
			{
				remarks = Filter.IdentifyVBCommentsAndStringLiterals(_uninstrumentedSrc);
			}
			else
			{
				remarks = Filter.IdentifyCommentsAndStringLiterals(_uninstrumentedSrc);
			}

			string instrumentedSrc = null;
			CoveragePoint[] points;

			if (filename.EndsWith(".vb") && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(236) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(232) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234))
			{
				points = new VbInstrumenter(baseCoverageIndex, _uninstrumentedSrc, filename).Do(out instrumentedSrc, remarks);
			}
			else
			{
				points = new Instrumenter(baseCoverageIndex, _uninstrumentedSrc, filename).Do(out instrumentedSrc, remarks);
			}

			if (points.Length == 0 && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(237) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(234) && NCover.NCoverCheck.Add(233) && NCover.NCoverCheck.Add(236) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(235) && NCover.NCoverCheck.Add(235))
				return points;

			
			_debug("saving original " + filename);

			new DeinstrumentMethods.DifferentExtension().preinstrument(filename);

			using (Stream s = new FileStream(filename, FileMode.Create))
			{
				using (TextWriter writer = new StreamWriter(s))
				{
					writer.WriteLine(instrumentedSrc);
					writer.Flush();
					writer.Close();					
				}
				s.Close();
			}
			NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(233); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(230); NCover.NCoverCheck.Add(229); NCover.NCoverCheck.Add(232); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(231); NCover.NCoverCheck.Add(231); return points;
		}

	}
}














